import streamlit as st
import os
import logging
from datetime import datetime
from typing import Dict, List, Tuple, Optional, Any

from ..core.kms_provider import KMSProvider
from ..core.kms_integration import KMSIntegration
from ..core.keychain import SystemKeychain

# 配置日志
logger = logging.getLogger(__name__)

def render_kms_integration_ui(kms_integration: KMSIntegration, keychain: SystemKeychain):
    """
    渲染KMS集成界面
    
    Args:
        kms_integration: KMS集成实例
        keychain: 系统密钥链实例
    """
    st.header("🔐 密钥管理服务 (KMS) 集成")
    
    # 获取当前连接状态
    connection_status = kms_integration.get_connection_status()
    is_connected = connection_status["connected"]
    
    # 显示连接状态
    st.subheader("连接状态")
    status_col1, status_col2 = st.columns(2)
    
    with status_col1:
        if is_connected:
            st.success("✅ 已连接到KMS服务")
            st.write(f"服务提供商: {connection_status['provider_type']}")
            if connection_status["last_sync"]:
                st.write(f"上次同步: {connection_status['last_sync']}")
        else:
            st.error("❌ 未连接到KMS服务")
    
    with status_col2:
        if is_connected:
            st.write(f"已映射的密钥数量: {connection_status['mapped_keys_count']}")
            if st.button("断开连接"):
                if kms_integration.disconnect():
                    st.success("已成功断开KMS连接")
                    st.experimental_rerun()
                else:
                    st.error("断开连接失败")
    
    # 连接到KMS服务
    if not is_connected:
        render_kms_connection_form(kms_integration)
    else:
        # 显示密钥映射和操作
        render_key_mapping_section(kms_integration, keychain)

def render_kms_connection_form(kms_integration: KMSIntegration):
    """
    渲染KMS连接表单
    
    Args:
        kms_integration: KMS集成实例
    """
    st.subheader("连接到KMS服务")
    
    with st.form("kms_connection_form"):
        # KMS提供商选择
        provider_type = st.selectbox(
            "选择KMS提供商",
            options=["azure", "hashicorp"],
            format_func=lambda x: "Azure Key Vault" if x == "azure" else "HashiCorp Vault"
        )
        
        # 根据提供商类型显示不同的连接参数
        if provider_type == "azure":
            st.write("Azure Key Vault 连接参数")
            tenant_id = st.text_input("租户ID (Tenant ID)", key="azure_tenant_id")
            client_id = st.text_input("客户端ID (Client ID)", key="azure_client_id")
            client_secret = st.text_input("客户端密钥 (Client Secret)", type="password", key="azure_client_secret")
            vault_url = st.text_input("Key Vault URL", key="azure_vault_url", 
                                     placeholder="https://your-vault-name.vault.azure.net/")
            
            # 构建连接参数
            connection_params = {
                "tenant_id": tenant_id,
                "client_id": client_id,
                "client_secret": client_secret,
                "vault_url": vault_url
            }
            
            # 验证输入
            required_fields = ["tenant_id", "client_id", "client_secret", "vault_url"]
            missing_fields = [field for field in required_fields if not connection_params.get(field)]
            
        else:  # hashicorp
            st.write("HashiCorp Vault 连接参数")
            vault_addr = st.text_input("Vault 地址", key="hashi_addr", 
                                      placeholder="https://vault.example.com:8200")
            token = st.text_input("访问令牌", type="password", key="hashi_token")
            ca_cert_path = st.text_input("CA 证书路径（可选）", key="hashi_ca_cert")
            
            # 构建连接参数
            connection_params = {
                "vault_addr": vault_addr,
                "token": token
            }
            
            if ca_cert_path:
                connection_params["ca_cert_path"] = ca_cert_path
                
            # 验证输入
            required_fields = ["vault_addr", "token"]
            missing_fields = [field for field in required_fields if not connection_params.get(field)]
            
        # 提交按钮
        submit_disabled = len(missing_fields) > 0
        submit_help = f"请填写所有必填字段: {', '.join(missing_fields)}" if submit_disabled else ""
        
        submitted = st.form_submit_button("连接")
        if submit_help:
            st.warning(submit_help)
            
        if submitted and not submit_disabled:
            with st.spinner("正在连接到KMS服务..."):
                if kms_integration.connect(provider_type, **connection_params):
                    st.success(f"已成功连接到 {provider_type} KMS服务")
                    st.experimental_rerun()
                else:
                    st.error("连接到KMS服务失败，请检查连接参数")

def render_key_mapping_section(kms_integration: KMSIntegration, keychain: SystemKeychain):
    """
    渲染密钥映射部分
    
    Args:
        kms_integration: KMS集成实例
        keychain: 系统密钥链实例
    """
    st.subheader("密钥映射管理")
    
    # 获取当前映射
    mapped_keys = kms_integration.get_mapped_keys()
    
    # 获取本地密钥列表
    local_keys = keychain.list_keys()
    
    # 显示当前映射
    if mapped_keys:
        st.write("当前映射的密钥:")
        
        for local_key_id, kms_key_id in mapped_keys.items():
            col1, col2, col3 = st.columns([3, 3, 2])
            with col1:
                st.write(f"本地密钥: {local_key_id}")
            with col2:
                st.write(f"KMS密钥: {kms_key_id}")
            with col3:
                # 操作按钮
                if st.button("解除映射", key=f"unmap_{local_key_id}"):
                    if kms_integration.unmap_local_key(local_key_id):
                        st.success(f"已解除密钥 {local_key_id} 的映射")
                        st.experimental_rerun()
                    else:
                        st.error("解除映射失败")
                
                if st.button("同步", key=f"sync_{local_key_id}"):
                    success, message = kms_integration.sync_key_from_kms(local_key_id)
                    if success:
                        st.success(message)
                    else:
                        st.error(message)
                        
                if st.button("轮换", key=f"rotate_{local_key_id}"):
                    success, message = kms_integration.rotate_key_with_kms(local_key_id)
                    if success:
                        st.success(message)
                    else:
                        st.error(message)
    else:
        st.info("暂无映射的密钥")
    
    # 添加新映射
    st.subheader("添加新映射")
    
    # 获取可用的本地密钥（排除已映射的）
    unmapped_local_keys = [k for k in local_keys if k not in mapped_keys]
    
    if unmapped_local_keys:
        col1, col2 = st.columns(2)
        
        with col1:
            st.write("从本地映射到KMS")
            
            with st.form("map_local_to_kms"):
                selected_local_key = st.selectbox(
                    "选择本地密钥",
                    options=unmapped_local_keys
                )
                
                # 获取KMS中可用的密钥
                try:
                    kms_keys, error = kms_integration.list_available_kms_keys()
                    if error:
                        st.error(f"获取KMS密钥失败: {error}")
                        kms_keys = []
                except Exception as e:
                    st.error(f"获取KMS密钥时出错: {str(e)}")
                    kms_keys = []
                
                if kms_keys:
                    # 显示可用的KMS密钥
                    kms_key_options = [k["id"] for k in kms_keys]
                    selected_kms_key = st.selectbox(
                        "选择KMS密钥",
                        options=kms_key_options
                    )
                    
                    submitted = st.form_submit_button("映射密钥")
                    if submitted:
                        if kms_integration.map_local_key_to_kms(selected_local_key, selected_kms_key):
                            st.success(f"已成功将本地密钥 {selected_local_key} 映射到KMS密钥 {selected_kms_key}")
                            st.experimental_rerun()
                        else:
                            st.error("映射密钥失败")
                else:
                    st.warning("KMS中没有可用的密钥")
                    st.form_submit_button("映射密钥", disabled=True)
        
        with col2:
            st.write("在KMS中创建新密钥")
            
            with st.form("create_kms_key"):
                key_name = st.text_input("密钥名称")
                key_desc = st.text_input("密钥描述(可选)")
                
                submitted = st.form_submit_button("创建KMS密钥")
                if submitted and key_name:
                    with st.spinner("正在创建KMS密钥..."):
                        kms_key_id, error = kms_integration.create_key_in_kms(key_name, key_desc)
                        if not error:
                            st.success(f"已成功创建KMS密钥: {kms_key_id}")
                        else:
                            st.error(f"创建KMS密钥失败: {error}")
    else:
        st.info("所有本地密钥都已映射")

def render_kms_dashboard(kms_integration: KMSIntegration):
    """
    渲染KMS仪表板
    
    Args:
        kms_integration: KMS集成实例
    """
    st.subheader("KMS仪表板")
    
    if not kms_integration.is_connected():
        st.warning("未连接到KMS服务，无法显示仪表板")
        return
    
    # 获取KMS中的密钥列表
    keys, error = kms_integration.list_available_kms_keys()
    if error:
        st.error(f"获取KMS密钥失败: {error}")
        return
    
    # 显示密钥统计信息
    st.write(f"KMS中的密钥总数: {len(keys)}")
    
    # 按类型分组
    key_types = {}
    for key in keys:
        key_type = key.get("key_type", "未知")
        if key_type not in key_types:
            key_types[key_type] = 0
        key_types[key_type] += 1
    
    # 显示按类型分组的统计信息
    st.write("按类型分组的密钥统计:")
    for key_type, count in key_types.items():
        st.write(f"- {key_type}: {count}")
    
    # 显示密钥详细信息
    st.write("密钥列表:")
    for key in keys:
        expander = st.expander(f"{key['name']} ({key['id']})")
        with expander:
            for k, v in key.items():
                st.write(f"{k}: {v}") 